/*
 * Copyright (C) 2011-2013 Eric Lasota
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#ifndef __RDX_OPCODES_HPP__
#define __RDX_OPCODES_HPP__

namespace RDX
{
	namespace Programmability
	{
		namespace OpArgs
		{
			enum OpArgs
			{
				INT1 = 1,
				INT2 = 2,
				INTVAR = 4,
				RES = 8,
				STR = 16,
			};
		};

		struct OpcodeInfo
		{
			UInt8 paramFlags;
		};

		typedef Byte InstructionOpcode;

		enum Opcode
		{
			OP_startbarrier,
			OP_endbarrier,
			OP_throw,
			OP_try,
			OP_catch,
			OP_trycast,
			OP_jump,
			OP_jumpif,
			OP_jumpifnot,
			OP_jumpiftrue,
			OP_jumpiffalse,
			OP_jumpifequal,
			OP_jumpifnotequal,
			OP_call,
			OP_callvirtual,
			OP_calldelegate,
			OP_alloclocal,
			OP_createlocal,
			OP_removelocal,
			OP_pushempty,
			OP_newinstance,
			OP_newinstanceset,
			OP_null,
			OP_pinlocal,
			OP_tovarying,
			OP_arrayindex,
			OP_property,
			OP_move,
			OP_load,
			OP_clone,
			OP_pop,
			OP_cast,
			OP_localref,
			OP_return,
			OP_hash,
			OP_res,
			OP_constant,
			OP_constant_str,
			OP_switch,
			OP_iteratearray,

			OP_Count,
		};

		static const OpcodeInfo OPCODE_INFO[] =
		{
			//OP_startbarrier,
			{ OpArgs::INT1 },

			//OP_endbarrier,
			{ 0 },

			//OP_throw,
			{ 0 },

			//OP_try,
			{ OpArgs::INT1 | OpArgs::INT2 },

			//OP_catch,
			{ OpArgs::RES },

			//OP_trycast,
			{ OpArgs::INT1 | OpArgs::RES },

			//OP_jump,
			{ OpArgs::INT1 },

			//OP_jumpif,
			{ OpArgs::INT1 | OpArgs::RES },

			//OP_jumpifnot,
			{ OpArgs::INT1 | OpArgs::RES  },

			//OP_jumpiftrue,
			{ OpArgs::INT1 },

			//OP_jumpiffalse,
			{ OpArgs::INT1 },

			//OP_jumpifequal,
			{ OpArgs::INT1 },

			//OP_jumpifnotequal,
			{ OpArgs::INT1 },

			//OP_call,
			{ OpArgs::RES },

			//OP_callvirtual,
			{ OpArgs::RES },

			//OP_calldelegate,
			{ OpArgs::RES },

			//OP_alloclocal,
			{ OpArgs::RES },

			//OP_createlocal,
			{ OpArgs::RES },

			//OP_removelocal,
			{ 0 },

			//OP_pushempty,
			{ OpArgs::RES },

			//OP_newinstance,
			{ OpArgs::INT1 | OpArgs::RES },

			//OP_newinstanceset,
			{ OpArgs::INT1 | OpArgs::INTVAR | OpArgs::RES },

			//OP_null,
			{ 0 },

			//OP_pinlocal,
			{ 0 },

			//OP_tovarying,
			{ 0 },

			//OP_arrayindex,
			{ OpArgs::INT1 },

			//OP_property,
			{ OpArgs::INT1 },

			//OP_move,
			{ 0 },

			//OP_load,
			{ 0 },

			//OP_clone,
			{ OpArgs::INT1 | OpArgs::INT2 },

			//OP_pop,
			{ 0 },

			//OP_cast,
			{ OpArgs::RES },

			//OP_localref,
			{ OpArgs::INT1 },

			//OP_return,
			{ OpArgs::INT1 },

			//OP_hash,
			{ 0 },

			//OP_res,
			{ OpArgs::RES },

			//OP_constant,
			{ OpArgs::RES | OpArgs::INT1 },

			//OP_constant_str,
			{ OpArgs::RES | OpArgs::STR },

			//OP_switch,
			{ OpArgs::RES | OpArgs::INT1 },

			//OP_iteratearray
			{ OpArgs::INT1 | OpArgs::INT2 },

			//OP_is
			{ OpArgs::RES | OpArgs::INT1 },
		};

		static const char *OPCODE_NAMES[] =
		{
			"OP_startbarrier",
			"OP_endbarrier",
			"OP_throw",
			"OP_try",
			"OP_catch",
			"OP_trycast",
			"OP_jump",
			"OP_jumpif",
			"OP_jumpifnot",
			"OP_jumpiftrue",
			"OP_jumpiffalse",
			"OP_jumpifequal",
			"OP_jumpifnotequal",
			"OP_call",
			"OP_callvirtual",
			"OP_calldelegate",
			"OP_alloclocal",
			"OP_createlocal",
			"OP_removelocal",
			"OP_pushempty",
			"OP_newinstance",
			"OP_newinstanceset",
			"OP_null",
			"OP_pinlocal",
			"OP_tovarying",
			"OP_arrayindex",
			"OP_property",
			"OP_move",
			"OP_load",
			"OP_clone",
			"OP_pop",
			"OP_cast",
			"OP_localref",
			"OP_return",
			"OP_hash",
			"OP_res",
			"OP_constant",
			"OP_constant_str",
			"OP_switch",
			"OP_iteratearray",
		};
	};
};

#endif
